package com.yubest.demo.advice;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yubest.demo.anno.SafetyProcess;
import com.yubest.demo.dto.Response;
import com.yubest.demo.dto.ResponseSign;
import com.yubest.demo.util.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Base64;

/**
 * @Description：后置响应加密处理逻辑
 */
@ControllerAdvice
@Slf4j
public class MyResponseBodyAdvice implements ResponseBodyAdvice {


    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        SafetyProcess process = methodParameter.getMethodAnnotation(SafetyProcess.class);
        //如果带有安全注解且标记为加密，测进行加密操作
        return null != process && process.responeEncode();
    }

    /**
     * 约定，响应方加密算法：
     * 1.对源数据转换成json字符串
     * 2.然后调用aes加密
     * @param o
     * @param methodParameter
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass,
                                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        Object data = null;
        //如果是rest接口统一封装返回对象
        if (o instanceof Response) {
            Response res = (Response) o;
            //如果返回成功
            if (res.isOk()) {
                data = res.getData();
            } else {
                return o;
            }
        }
        else  if (o instanceof ResponseSign) {
            Object datas = ((ResponseSign<?>) o).getData();
            //加密
            String e = AESUtil.encode(datas);
            ResponseSign mp = new ResponseSign();
            mp.setData(e);
            mp.setMessage(((ResponseSign<?>) o).getMessage());
            mp.setCode(((ResponseSign<?>) o).getCode());
            mp.setSign(((ResponseSign<?>) o).getSign());
            mp.setTimestamp(((ResponseSign<?>) o).getTimestamp());
            mp.setVersion(((ResponseSign<?>) o).getVersion());

            return mp;
        }
        else {
            data = o;
        }

        //加密
        return Response.success(AESUtil.encode(data));

//        if (null != data) {
//            ObjectMapper objectMapper = new ObjectMapper();
//            try {
//                String bodyStr = objectMapper.writeValueAsString(o);
//                //加密
//                return Response.success(AESUtil.encode(bodyStr));
//            } catch (JsonProcessingException e) {
//                log.error("数据加密异常", e);
//            }
//        }
//        return o;

    }
}
